struct float4
{
	float x;
	float y;
	float z;
	float w;

	float4(const float _x, const float _y, const float _z, const float _w) :
		x(_x),
		y(_y),
		z(_z),
		w(_w)
	{
	}

	float4(const float f) :
		x(f),
		y(f),
		z(f),
		w(f)
	{
	}

	float4() :
		x(0),
		y(0),
		z(0),
		w(0)
	{ }

	const float4& operator=(const float& other)
	{
		x = other;
		y = other;
		z = other;
		w = other;

		return *this;
	}

	const float4& operator=(const float4& other)
	{
		x = other.x;
		y = other.y;
		z = other.z;
		w = other.w;

		return *this;
	}

	float4 operator*(const float4& other) const
	{
		float4 ret;
		ret.x = x*other.x;
		ret.y = y*other.y;
		ret.z = z*other.z;
		ret.w = w*other.w;
		return ret;
	}

	float4 operator*(const float& other) const
	{
		float4 ret;
		ret.x = x*other;
		ret.y = y*other;
		ret.z = z*other;
		ret.w = w*other;
		return ret;
	}

	float4 operator/(const float& other) const
	{
		float4 ret;
		ret.x = x/other;
		ret.y = y/other;
		ret.z = z/other;
		ret.w = w/other;
		return ret;
	}

	float4 operator+(const float4& other) const
	{
		float4 ret;
		ret.x = x+other.x;
		ret.y = y+other.y;
		ret.z = z+other.z;
		ret.w = w+other.w;
		return ret;
	}

	float4 operator+(const float& other) const
	{
		float4 ret;
		ret.x = x+other;
		ret.y = y+other;
		ret.z = z+other;
		ret.w = w+other;
		return ret;
	}

	float4 operator-(const float4& other) const
	{
		float4 ret;
		ret.x = x-other.x;
		ret.y = y-other.y;
		ret.z = z-other.z;
		ret.w = w-other.w;
		return ret;
	}
};

struct float3
{
	float x;
	float y;
	float z;

	float3(const float& f) :
		x(f),
		y(f),
		z(f)
	{
	}

	float3(const float& _x, const float& _y, const float& _z) :
		x(_x),
		y(_y),
		z(_z)
	{
	}

	float3() :
		x(0),
		y(0),
		z(0)
	{ }

	const float3& operator=(const float& other)
	{
		x = other;
		y = other;
		z = other;

		return *this;
	}

	const float3& operator=(const float3& other)
	{
		x = other.x;
		y = other.y;
		z = other.z;

		return *this;
	}

	float3 operator*(const float3& other) const
	{
		float3 ret;
		ret.x = x*other.x;
		ret.z = y*other.y;
		ret.y = z*other.z;
		return ret;
	}

	float3 operator*(const float& other) const
	{
		float3 ret;
		ret.x = x*other;
		ret.y = y*other;
		ret.z = z*other;
		return ret;
	}

	float3 operator/(const float& other) const
	{
		float3 ret;
		ret.x = x/other;
		ret.y = y/other;
		ret.z = z/other;
		return ret;
	}

	float3 operator+(const float3& other) const
	{
		float3 ret;
		ret.x = x+other.x;
		ret.y = y+other.y;
		ret.z = z+other.z;
		return ret;
	}

	float3 operator+(const float& other) const
	{
		float3 ret;
		ret.x = x+other;
		ret.y = y+other;
		ret.z = z+other;
		return ret;
	}

	float3 operator-(const float3& other) const
	{
		float3 ret;
		ret.x = x-other.x;
		ret.y = y-other.y;
		ret.z = z-other.z;
		return ret;
	}
};

struct float2
{
	float x;
	float y;

	float2() :
		x(0),
		y(0)
	{ }

	float2(const float _x, const float _y) :
		x(_x),
		y(_y)
	{
	}

	float2(const float f) :
		x(f),
		y(f)
	{
	}

	const float2& operator=(const float& other)
	{
		x = other;
		y = other;

		return *this;
	}

	float2 operator*(const float2& other) const
	{
		float2 ret;
		ret.x = x*other.x;
		ret.y = y*other.y;
		return ret;
	}

	float2 operator*(const float& other) const
	{
		float2 ret;
		ret.x = x*other;
		ret.y = y*other;
		return ret;
	}

	float2 operator/(const float& other) const
	{
		float2 ret;
		ret.x = x/other;
		ret.y = y/other;
		return ret;
	}

	float2 operator+(const float2& other) const
	{
		float2 ret;
		ret.x = x+other.x;
		ret.y = y+other.y;
		return ret;
	}

	float2 operator+(const float& other) const
	{
		float2 ret;
		ret.x = x+other;
		ret.y = y+other;
		return ret;
	}

	float2 operator-(const float2& other) const
	{
		float2 ret;
		ret.x = x-other.x;
		ret.y = y-other.y;
		return ret;
	}
};

struct float2x2
{
	float _m11, _m12;
	float _m21, _m22;

	float2x2() :
		_m11(1.0f),
		_m12(0.0f),
		_m21(0.0f),
		_m22(1.0f)
	{
	}

	float2 operator*(const float2& vec)
	{
		return float2(vec.x*_m11 + vec.y*_m12, vec.x*_m21 + vec.y*_m22);
	}

	float2x2 operator*(const float2x2& m)
	{
		float2x2 ret;
		ret._m11 = _m11*m._m11 + _m12*m._m21;
		ret._m12 = _m11*m._m12 + _m12*m._m22;
		ret._m21 = _m21*m._m11 + _m22*m._m21;
		ret._m22 = _m21*m._m12 + _m22*m._m22;
		return ret;
	}
};